/** 更新图元参数
 * @ 标  识: hchhIOT
 * @ 作  者: 阿拉丁矿工 黄传鸿 <hchhyzc@foxmail.com>
 */

/* ================================================================================================ */
// 🍀引入
/* ================================================================================================ */
import { ref, reactive, onMounted, toRefs, watch, onUnmounted, computed } from 'vue'
import * as d3 from "d3"
import { useMessage } from 'naive-ui'

/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// 🐸 图元端函数引入
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
import {
  onGetLineMiddle,
  onGetCircleBisectionPoint,
  onAnimationHandle,
  onGetPelDataVal,
  onGetEquipDataVal,
  onPatternGenerator,//填充图案生成器
} from "@/functions"

/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// 🐸 引入存储
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
import { useCanvasStore } from "@/store/canvasStore"; // 画布
import { useWorkStore } from "@/store/workStore"; // 工作数据



/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
// 🐸 使用存储
/**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
const canvasStore = useCanvasStore(); // 画布
const workStore = useWorkStore(); // 设备数据
const message = useMessage()// 消息
/**———————————————————————————————————————————————————————————————————————————————————————————————— */
//                                ★ 类型
/**———————————————————————————————————————————————————————————————————————————————————————————————— */
/** 坐标类型 */
type CoordinateType = {
  x: number;
  y: number;
};
/** 位置-枚举 */
enum PlaceEnum {
  // -------------------| ★ 左
  TL = 'tl',  // 上左
  L = 'l',    // 左
  BL = 'bl',  // 下左
  // -------------------| ★ 中
  TM = 'tm',  // 上中
  M = 'm',    // 中间
  BM = 'bm',  // 下中
  // -------------------| ★ 右
  TR = 'tr',  // 上右
  radius = 'r',    // 右
  BR = 'br',  // 下右
}

/** 位置类型 */
type PlaceType = {
  // 🦢 ----------| ★ 左
  [PlaceEnum.TL]: CoordinateType,  /** 上左 */
  [PlaceEnum.L]?: CoordinateType,   /** 左   */
  [PlaceEnum.BL]?: CoordinateType,  /** 下左 */
  // 🦢 ----------| ★ 中
  [PlaceEnum.TM]?: CoordinateType,  /** 上中 */
  [PlaceEnum.M]: CoordinateType,   /** 中间 */
  [PlaceEnum.BM]?: CoordinateType,  /** 下中 */
  // 🦢 ----------| ★ 右
  [PlaceEnum.TR]?: CoordinateType,  /** 上右 */
  [PlaceEnum.radius]?: CoordinateType,   /** 右   */
  [PlaceEnum.BR]: CoordinateType,  /** 下右 */
}
/* ================================================================================================ */
//                                函数
/* ================================================================================================ */

/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ SVG图元
/**————————————————————————————————————————————————————————————————————————————————————————————————*/

/** 更新标签-线*/
const onUpdataHtmlLine = (pelInfo: any): any => {
 // console.log("✍ 更新标签-线");

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 转储、建立参数
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  //------------------------------|属性
  /** 坐标X1值 */
  let X1Val = Number(pelInfo.attrs.x1.val);
  /** 坐标Y1值 */
  let Y1Val = Number(pelInfo.attrs.y1.val);
  /** 坐标X2值 */
  let X2Val = Number(pelInfo.attrs.x2.val);
  /** 坐标Y2值 */
  let Y2Val = Number(pelInfo.attrs.y2.val);
  /** 轮廓颜色值*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线值 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移值 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度值 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-X1坐标 */
  let AnHtmlX1 = ``;
  /** 动画标签-Y1坐标 */
  let AnHtmlY1 = ``;
  /** 动画标签-X2坐标 */
  let AnHtmlX2 = ``;
  /** 动画标签-Y2坐标 */
  let AnHtmlY2 = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /**动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;


  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateVal rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    if (
      pelInfo.animations.rotate.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      rotateVal = Number(AnVal);
    }
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleVal scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "", "XML");
    if (
      pelInfo.animations.scale.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      scaleVal = Number(AnVal);
    }
    scaleAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXVal skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "", "XML");
    if (
      pelInfo.animations.skewX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewXVal = Number(AnVal);
    }
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYVal skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "", "XML");
    if (
      pelInfo.animations.skewY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewYVal = Number(AnVal);
    }
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 坐标x1 X1Val;AnHtmlX1
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.x1.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.x1,
      "x1",
      "XML"
    );
    if (
      pelInfo.animations.x1.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      X1Val = Number(AnVal);
    }
    AnHtmlX1 = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 坐标y1 Y1Val;AnHtmlY1
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.y1.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.y1,
      "y1",
      "XML"
    );
    if (
      pelInfo.animations.y1.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      Y1Val = Number(AnVal);
    }
    AnHtmlY1 = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 坐标x2 X2Val;AnHtmlX2
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.x2.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.x2,
      "x2",
      "XML"
    );
    if (
      pelInfo.animations.x2.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      X2Val = Number(AnVal);
    }
    AnHtmlX2 = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 坐标y2 Y2Val;AnHtmlY2
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.y2.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.y2,
      "y2",
      "XML"
    );
    if (pelInfo.animations.y2.opt_an_model !== 3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/) {
      Y2Val = Number(AnVal);
    }
    AnHtmlY2 = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDashoffset.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    //-----------------------------------|属性动画
    AnHtmlX1 +// 坐标x1
    AnHtmlY1 +// 坐标y1
    AnHtmlX2 +// 坐标x2
    AnHtmlY2 +// 坐标y2
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    strokeAnHtml + //♈轮廓颜色
    opacityAnHtml; //♈元素透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    tl: { x: 0, y: 0 },
    tm: { x: 0, y: 0 },
    tr: { x: 0, y: 0 },
    l: { x: 0, y: 0 },
    m: { x: 0, y: 0 },
    r: { x: 0, y: 0 },
    bl: { x: 0, y: 0 },
    bm: { x: 0, y: 0 },
    br: { x: 0, y: 0 },
  };

  /** 图元类型 */
  let PelType = pelInfo.type;
  if (PelType === "horizontaLine" /*水平线*/) {
    /** 线起点*/
    let StartPoint: CoordinateType = {
      x: X1Val,
      y: Y1Val,
    };
    /** 线终点*/
    let EndPoint: CoordinateType = {
      x: X2Val,
      y: Y2Val,
    };
    /** 线中间点 */
    let MiddlePoint: CoordinateType = onGetLineMiddle(StartPoint, EndPoint); //获取线-中点
    /** 位置点 */
    PlacePoint.tl = StartPoint;
    PlacePoint.l = StartPoint;
    PlacePoint.m = MiddlePoint;
    PlacePoint.r = EndPoint;
    PlacePoint.br = EndPoint;
  }

  if (PelType === "verticalLine" /*垂直线*/) {
    /** 线起点*/
    let StartPoint: CoordinateType = {
      x: X1Val,
      y: Y1Val,
    };
    /** 线终点*/
    let EndPoint: CoordinateType = {
      x: X2Val,
      y: Y2Val,
    };
    /** 线中间点 */
    let MiddlePoint: CoordinateType = onGetLineMiddle(StartPoint, EndPoint); //获取线-中点
    /** 位置点 */
    PlacePoint.tl = StartPoint;
    PlacePoint.tm = StartPoint;
    PlacePoint.m = MiddlePoint;
    PlacePoint.bm = EndPoint;
    PlacePoint.br = EndPoint;
  }

  if (PelType === "slantLine" /*斜线*/) {
    /** 线起点*/
    let StartPoint: CoordinateType = {
      x: X1Val,
      y: Y1Val,
    };
    /** 线终点*/
    let EndPoint: CoordinateType = {
      x: X2Val,
      y: Y2Val,
    };
    /** 线中间点 */
    let MiddlePoint: CoordinateType = onGetLineMiddle(StartPoint, EndPoint); //获取线-中点
    /** 位置点 */
    PlacePoint.tl = StartPoint;
    PlacePoint.tm = StartPoint;
    PlacePoint.m = MiddlePoint;
    PlacePoint.bm = EndPoint;
    PlacePoint.br = EndPoint;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
   // console.log(pidVal)
    htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><line id=${idVal} x1='${X1Val}' y1='${Y1Val}' x2='${X2Val}' y2='${Y2Val}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke='${strokeVal}'>${anHtmlSet}</line></g></svg></div>`;
  }
  if (pidVal === "none") {
   // console.log(pidVal)
    htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><line id=${idVal} x1='${X1Val}' y1='${Y1Val}' x2='${X2Val}' y2='${Y2Val}' stroke-width='${strokeWidthVal}'  stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke='${strokeVal}'>${anHtmlSet}</line></g>`;
  }

 // console.log(htmlLabel)
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-圆 */
const onUpdataHtmlCircle = (pelInfo: any): any => {
 // console.log("✍ 更新标签-圆")
 // console.log(pelInfo)

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 水平坐标值 */
  let leftVal = Number(pelInfo.attrs.cx.val);
  /** 垂直坐标值 */
  let topVal = Number(pelInfo.attrs.cy.val);
  /** 圆半径 */
  let RadiusVal = Number(pelInfo.attrs.radius.val);

  //------------------------------------------------ 填充
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = (pelInfo.attrs.fill.fillOpt);
  /** 填充图案*/
  let fillPatternVal = Number(pelInfo.attrs.fill.fillPattern);
  /** 填充尺寸*/
  let fillSizeVal = Number(pelInfo.attrs.fill.fillSize);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 声明动画标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-水平动画 */
  let leftAnHtml = ``;
  /** 动画标签-垂直动画 */
  let topAnHtml = ``;
  /** 动画标签-圆半径 */
  let radiusAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateVal rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    if (
      pelInfo.animations.rotate.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      rotateVal = Number(AnVal);
    }
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleVal scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "", "XML");
    if (
      pelInfo.animations.scale.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      scaleVal = Number(AnVal);
    }
    scaleAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXVal skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "", "XML");
    if (
      pelInfo.animations.skewX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewXVal = Number(AnVal);
    }
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYVal skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "", "XML");
    if (
      pelInfo.animations.skewY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewYVal = Number(AnVal);
    }
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动_动画 leftVal;leftAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.cx.enable) {
   // console.log("圆CX坐标_水平移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.cx, "cx", "XML");
    if (
      pelInfo.animations.cx.opt_an_model !== 3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      leftVal = Number(AnVal);
    }
    leftAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 垂直移动_动画 topVal;topAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.cy.enable) {
   // console.log("圆CY坐标_垂直移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.cy, "cy", "XML");
    if (
      pelInfo.animations.cy.opt_an_model !== 3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      topVal = Number(AnVal);
    }
    topAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 圆半径 RadiusVal;radiusAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.radius.enable) {
   // console.log("圆半径 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.radius, "r", "XML");
    if (
      pelInfo.animations.radius.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      RadiusVal = Number(AnVal);
    }
    radiusAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
   // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
   // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
   // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|变换动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动

    //-----------------------------------|属性动画
    leftAnHtml + //♈圆CX坐标
    topAnHtml + //♈圆CY坐标
    radiusAnHtml + //♈圆半径
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    /** 上左 */
    tl: {
      x: leftVal - RadiusVal,
      y: topVal - RadiusVal,
    },
    /** 上中 */
    tm: {
      x: leftVal,
      y: topVal - RadiusVal,
    },
    /** 上右 */
    tr: {
      x: leftVal + RadiusVal,
      y: topVal - RadiusVal,
    },
    /** 左 */
    l: {
      x: leftVal - RadiusVal,
      y: topVal,
    },
    /** 中间 */
    m: {
      x: leftVal,
      y: topVal,
    },
    /** 右 */
    r: {
      x: leftVal + RadiusVal,
      y: topVal,
    },
    /** 下左 */
    bl: {
      x: leftVal - RadiusVal,
      y: topVal + RadiusVal,
    },
    /** 下中 */
    bm: {
      x: leftVal,
      y: topVal + RadiusVal,
    },
    /** 下右 */
    br: {
      x: leftVal + RadiusVal,
      y: topVal + RadiusVal,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none") {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g></svg></div>`;
    }
    if (pidVal === "none") {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {

    // 🐸 ★ 默认
    let defs = onPatternGenerator(fillPatternVal, fillVal, fillIdVal, fillSizeVal, fillRatioVal);
   // console.log(defs);

    if (pidVal !== "none") {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g></svg></div>`;
    }
    if (pidVal === "none") {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {

    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }

    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g></svg></div>`;
    }

    if (pidVal === "none"/*父id为空*/) {
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g>`;
    }

  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none") {
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g></svg></div>`;
    }
    if (pidVal === "none") {
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<circle id=${idVal} cx='${leftVal}' cy='${topVal}' r='${RadiusVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</circle></g>`;
    }
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点; JSON.parse(JSON.stringify(workStore.pels))
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);
      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-椭圆 */
const onUpdataHtmlEllipse = (pelInfo: any): any => {
 // console.log("✍ 更新标签-椭圆");
 // console.log(pelInfo);
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 水平坐标值 */
  let leftVal = Number(pelInfo.attrs.cx.val);
  /** 垂直坐标值 */
  let topVal = Number(pelInfo.attrs.cy.val);
  /** 圆半径X */
  let RXVal = Number(pelInfo.attrs.radiusX.val);
  /** 圆半径Y */
  let RYVal = Number(pelInfo.attrs.radiusY.val);
  //------------------------------------------------
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = Number(pelInfo.attrs.fill.fillOpt);
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充图案*/
  let fillPatternVal = String(pelInfo.attrs.fill.fillPattern);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 声明动画标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-水平坐标值 */
  let leftAnHtml = ``;
  /** 动画标签-圆CY坐标 */
  let topAnHtml = ``;
  /** 动画标签-圆半径X */
  let rxAnHtml = ``;
  /** 动画标签-圆半径Y */
  let ryAnHtml = ``;

  //------------------------------|公共-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 圆CX坐标_水平移动_动画 leftVal;leftAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.cx.enable) {
   // console.log("圆CX坐标_水平移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.cx, "cx", "XML");
    if (
      pelInfo.animations.cx.opt_an_model !== 3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      leftVal = Number(AnVal);
    }
    leftAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 圆CY坐标_垂直移动_动画 topVal;topAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.cy.enable) {
   // console.log("圆CY坐标_垂直移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.cy, "cy", "XML");
    if (
      pelInfo.animations.cy.opt_an_model !== 3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      topVal = Number(AnVal);
    }
    topAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 圆半径X RXVal;rxAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.radiusX.enable) {
   // console.log("圆半径 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.radiusX, "rx", "XML");
    if (
      pelInfo.animations.radiusX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      RXVal = Number(AnVal);
    }
    rxAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 圆半径Y RYVal;ryAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.radiusY.enable) {
   // console.log("圆半径 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.radiusY, "ry", "XML");
    if (
      pelInfo.animations.radiusY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      RYVal = Number(AnVal);
    }
    ryAnHtml = String(AnHtml);
  }

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDashoffset.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
   // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.fill.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
   // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
   // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    leftAnHtml +
    topAnHtml +
    rxAnHtml +
    ryAnHtml +
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    /** 上左 */
    tl: {
      x: leftVal - RXVal,
      y: topVal - RYVal,
    },
    /** 上中 */
    tm: {
      x: leftVal,
      y: topVal - RYVal,
    },
    /** 上右 */
    tr: {
      x: 0,
      y: 0,
    },
    /** 左 */
    l: {
      x: leftVal - RXVal,
      y: topVal,
    },
    /** 中间 */
    m: {
      x: leftVal,
      y: topVal,
    },
    /** 右 */
    r: {
      x: leftVal + RXVal,
      y: topVal,
    },
    /** 下左 */
    bl: {
      x: leftVal + RXVal,
      y: topVal + RYVal,
    },
    /** 下中 */
    bm: {
      x: leftVal,
      y: topVal + RYVal,
    },
    /** 下右 */
    br: {
      x: leftVal + RXVal,
      y: topVal + RYVal,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}'  fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}'  fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<ellipse id=${idVal} cx='${leftVal}' cy='${topVal}' rx='${RXVal}' ry='${RYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</ellipse></g>`;
    }
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-三点弧线 */
const onUpdataHtmlArc = (pelInfo: any): any => {
 // console.log("✍ 更新标签-三点弧线");
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 转储、建立参数
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 开始点X值 */
  let startXVal = Number(pelInfo.attrs.startX.val);
  /** 开始点Y值 */
  let startYVal = Number(pelInfo.attrs.startY.val);
  /** 控制点X值 */
  let ctrlXVal = Number(pelInfo.attrs.ctrlX.val);
  /** 控制点Y值 */
  let ctrlYVal = Number(pelInfo.attrs.ctrlY.val);
  /** 终点X值 */
  let endXVal = Number(pelInfo.attrs.endX.val);
  /** 终点Y值 */
  let endYVal = Number(pelInfo.attrs.endY.val);
  /** 轮廓颜色值*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线值 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移值 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度值 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-开始点X */
  let startXAnHtml = ``;
  /** 动画标签-开始点Y */
  let startYAnHtml = ``;
  /** 动画标签-控制点X */
  let ctrlXAnHtml = ``;
  /** 动画标签-控制点Y */
  let ctrlYAnHtml = ``;
  /** 动画标签-终点X */
  let endXAnHtml = ``;
  /** 动画标签-终点Y */
  let endYAnHtml = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /**动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    /*开始点Y*/ startXAnHtml +
    /*开始点Y*/ startYAnHtml +
    /*控制点X*/ ctrlXAnHtml +
    /*控制点X*/ ctrlYAnHtml +
    /*终点X  */ endXAnHtml +
    /*终点X  */ endYAnHtml +
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    opacityAnHtml; //♈元素透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint = {
    /** 上左 */
    tl: {
      x: pelInfo.attrs.startX.val,
      y: pelInfo.attrs.startY.val,
    },
    start: {
      x: pelInfo.attrs.startX.val,
      y: pelInfo.attrs.startY.val,
    },
    ctrl: {
      x: pelInfo.attrs.ctrlX.val,
      y: pelInfo.attrs.ctrlY.val,
    },
    end: {
      x: pelInfo.attrs.endX.val,
      y: pelInfo.attrs.endY.val,
    },
    /** 下右 */
    br: {
      x: pelInfo.attrs.endX.val,
      y: pelInfo.attrs.endY.val,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
   // console.log(pidVal)
    htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${startXVal},${startYVal} Q${ctrlXVal},${ctrlYVal},${endXVal},${endYVal}' fill='rgba(0,0,0,0)' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}'; stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}'>${anHtmlSet}</path></g></svg></div>`;
  }
  if (pidVal === "none") {
   // console.log(pidVal)
    htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${startXVal},${startYVal} Q${ctrlXVal},${ctrlYVal},${endXVal},${endYVal}' fill='rgba(0,0,0,0)' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}'; stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}'>${anHtmlSet}</path></g>`;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-圆分多边形 */
const onUpdataHtmlCirclePolygon = (pelInfo: any) => {
 // console.log("✍ 更新标签-圆分多边形");
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 圆心坐标CX */
  let leftVal = Number(pelInfo.attrs.cx.val);
  /** 圆心坐标CY */
  let topVal = Number(pelInfo.attrs.cy.val);
  /** 圆半径 */
  let radius = Number(pelInfo.attrs.circleRadius.val);
  //------------------------------------------------
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = Number(pelInfo.attrs.fill.fillOpt);
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充图案*/
  let fillPatternVal = String(pelInfo.attrs.fill.fillPattern);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 求圆周上等分点的坐标
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /**等分数量 */
  let quantity = Number(pelInfo.attrs.quantity.val);
  /** 路径点*/
  let pathPoints = onGetCircleBisectionPoint(leftVal, topVal, radius, quantity);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-开始点X */
  let startXAnHtml = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDashoffset.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
   // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.fill.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
   // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
   // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    /*开始点Y*/ startXAnHtml +
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: leftVal - radius,
      y: topVal - radius,
    },
    /** 左 */
    l: {
      x: leftVal - radius,
      y: topVal,
    },
    /** 下左 */
    bl: {
      x: leftVal - radius,
      y: topVal + radius,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: leftVal,
      y: topVal - radius,
    },
    /** 中间 */
    m: {
      x: leftVal,
      y: topVal,
    },
    /** 下中 */
    bm: {
      x: leftVal,
      y: topVal + radius,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: leftVal + radius,
      y: topVal - radius,
    },
    /** 右 */
    r: {
      x: leftVal + radius,
      y: topVal,
    },
    /** 下右 */
    br: {
      x: leftVal + radius,
      y: topVal + radius,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 标签路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let PathAdd = "";
  for (let index = 1; index < pathPoints.length; index++) {
    let X = pathPoints[index].x;
    let Y = pathPoints[index].y;
    PathAdd = PathAdd + `L${X},${Y} `;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></svg></g></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M ${pathPoints[0].x},${pathPoints[0].y} ` +
        PathAdd +
        `z' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</path></g>`;
    }
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-矩形 */
const onUpdataHtmlRectangle = (pelInfo: any): any => {
 // console.log("✍ 更新标签-矩形");
 // console.log(pelInfo);
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** x坐标值 */
  let leftVal = Number(pelInfo.attrs.left.val);
  /** y坐标值 */
  let topVal = Number(pelInfo.attrs.top.val);
  /** 宽度值 */
  let widthVal = Number(pelInfo.attrs.width.val);
  /** 高度值 */
  let heightVal = Number(pelInfo.attrs.height.val);
  /** 圆角x值 */
  let FXVal = Number(pelInfo.attrs.fx.val);
  /** 圆角x值 */
  let FYVal = Number(pelInfo.attrs.fy.val);

  //------------------------------------------------ 填充
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = (pelInfo.attrs.fill.fillOpt);
  /** 填充图案*/
  let fillPatternVal = Number(pelInfo.attrs.fill.fillPattern);
  /** 填充尺寸*/
  let fillSizeVal = Number(pelInfo.attrs.fill.fillSize);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|公共-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-矩形宽度动画 */
  let rectWidthAnHtml = ``;
  /** 动画标签-矩形高度动画 */
  let rectHeightAnHtml = ``;
  /** 动画标签-水平动画 */
  let leftAnHtml = ``;
  /** 动画标签-垂直动画 */
  let topAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;



  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateVal rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "rotate", "XML");
    if (
      pelInfo.animations.rotate.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      rotateVal = Number(AnVal);
    }
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleVal scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    if (
      pelInfo.animations.scale.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      scaleVal = Number(AnVal);
    }
    scaleAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXVal skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    if (
      pelInfo.animations.skewX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewXVal = Number(AnVal);
    }
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYVal skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    if (
      pelInfo.animations.skewY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewYVal = Number(AnVal);
    }
    skewYAnHtml = String(AnHtml);
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 宽度_动画 widthVal;rectWidthAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rectWidth.enable) {
   // console.log("宽度_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rectWidth, "width", "XML");
    if (
      pelInfo.animations.left.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      widthVal = Number(AnVal);
    }
    rectWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 高度_动画 heightVal;rectHeightAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rectHeight.enable) {
   // console.log("高度_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rectHeight, "height", "XML");
    if (
      pelInfo.animations.left.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      heightVal = Number(AnVal);
    }
    rectHeightAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动_动画 leftVal;leftAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.left.enable) {
   // console.log("水平移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.left, "x", "XML");
    if (
      pelInfo.animations.left.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      leftVal = Number(AnVal);
    }
    leftAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 垂直移动_动画 topVal;topAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.top.enable) {
   // console.log("垂直移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.top, "y", "XML");
    if (
      pelInfo.animations.top.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      topVal = Number(AnVal);
    }
    topAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
   // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
   // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
   // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动

    //------------------------------|属性-动画
    rectWidthAnHtml + //♈矩形宽度动画
    rectHeightAnHtml + //♈矩形高度动画
    leftAnHtml + //♈水平移动
    topAnHtml + //♈垂直移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // ——————————————————————————————————————————————————————————————| ★ 位置点
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: leftVal,
      y: topVal,
    },
    /** 左 */
    l: {
      x: leftVal,
      y: topVal + heightVal / 2,
    },
    /** 下左 */
    bl: {
      x: leftVal,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: leftVal + widthVal / 2,
      y: topVal,
    },
    /** 中间 */
    m: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal / 2,
    },
    /** 下中 */
    bm: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: leftVal + widthVal,
      y: topVal,
    },
    /** 右 */
    r: {
      x: leftVal + widthVal,
      y: topVal + heightVal / 2,
    },
    /** 下右 */
    br: {
      x: leftVal + widthVal,
      y: topVal + heightVal,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='${fillVal}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    // 🐸 ★ 默认
    let defs = onPatternGenerator(fillPatternVal, fillVal, fillIdVal, fillSizeVal, fillRatioVal);
   // console.log(defs);
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height=${heightVal} rx=${FXVal} ry=${FYVal} fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel = `<g style='transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<rect id=${idVal} x='${leftVal}' y='${topVal}' width='${widthVal}' height='${heightVal}' rx='${FXVal}' ry='${FYVal}' fill='url(#${fillIdVal})' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}'>${anHtmlSet}</rect></g>`;
    }
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-多边形*/
const onUpdataHtmlPolygon = (pelInfo: any): any => {
 // console.log("✍ 更新标签-圆弧");

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  //------------------------------------------------
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = Number(pelInfo.attrs.fill.fillOpt);
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充图案*/
  let fillPatternVal = String(pelInfo.attrs.fill.fillPattern);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 线链接样式 */
  let strokeLinejoinVal = String(pelInfo.attrs.strokeLinejoin.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
   // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
   // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
   // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: 10,
      y: 10,
    },
    /** 左 */
    l: {
      x: 10,
      y: 10,
    },
    /** 下左 */
    bl: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: 10,
      y: 10,
    },
    /** 中间 */
    m: {
      x: 10,
      y: 10,
    },
    /** 下中 */
    bm: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: 10,
      y: 10,
    },
    /** 右 */
    r: {
      x: 10,
      y: 10,
    },
    /** 下右 */
    br: {
      x: 10,
      y: 10,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 标签路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 路径点*/
  let pathPoints = pelInfo.attrs.pathPoints.val;
 // console.log(pathPoints)

  /** 路径追加点*/
  let PathAdd = "";
  for (let index = 1; index < pathPoints.length; index++) {
    let X = pathPoints[index].x;
    let Y = pathPoints[index].y;
    PathAdd = PathAdd + `L${X} ${Y} `;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  //填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='${fillVal}'>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`

    if (pidVal !== "none"/*父id不为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g></svg></div>`;
    }
    if (pidVal === "none"/*父id为空*/) {
     // console.log(pidVal)
      htmlLabel =
        `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${defs}<path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
        PathAdd +
        ` Z' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' stroke-opacity='${strokeOpacityVal}' fill-opacity='${fillOpacityVal}' fill='url(#${fillIdVal})' '>${anHtmlSet}</path></g>`;
    }
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-折线*/
const onUpdataHtmlPolyline = (pelInfo: any): any => {
 // console.log("✍ 更新标签-折线")

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 线链接样式 */
  let strokeLinejoinVal = String(pelInfo.attrs.strokeLinejoin.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-开始点X */
  let startXAnHtml = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    /*开始点Y*/ startXAnHtml +
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml; //♈元素透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: 10,
      y: 10,
    },
    /** 左 */
    l: {
      x: 10,
      y: 10,
    },
    /** 下左 */
    bl: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: 10,
      y: 10,
    },
    /** 中间 */
    m: {
      x: 10,
      y: 10,
    },
    /** 下中 */
    bm: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: 10,
      y: 10,
    },
    /** 右 */
    r: {
      x: 10,
      y: 10,
    },
    /** 下右 */
    br: {
      x: 10,
      y: 10,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 标签路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 路径点*/
  let pathPoints = pelInfo.attrs.pathPoints.val;
  /** 路径追加点*/
  let PathAdd = "";
  for (let index = 1; index < pathPoints.length; index++) {
    let X = pathPoints[index].x;
    let Y = pathPoints[index].y;
    PathAdd = PathAdd + `L${X},${Y} `;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
   // console.log(pidVal)
    htmlLabel =
      `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
      PathAdd +
      `' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g></svg></div>`;
  }
  if (pidVal === "none") {
   // console.log(pidVal)
    htmlLabel =
      `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='M${pathPoints[0].x} ${pathPoints[0].y} ` +
      PathAdd +
      `' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' stroke-linejoin='${strokeLinejoinVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g>`;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-路径*/
const onUpdataHtmlPath = (pelInfo: any): any => {
 // console.log("✍ 更新标签-路径");

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 轮廓颜色*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 线端样式 */
  let strokeLinecapVal = String(pelInfo.attrs.strokeLinecap.val);
  /** 虚线 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|变换-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-开始点X */
  let startXAnHtml = ``;

  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;



  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "scale", "XML");
    scaleAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "skewX", "XML");
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "skewY", "XML");
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动

    /*开始点Y*/ startXAnHtml +
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml; //♈元素透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: 10,
      y: 10,
    },
    /** 左 */
    l: {
      x: 10,
      y: 10,
    },
    /** 下左 */
    bl: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: 10,
      y: 10,
    },
    /** 中间 */
    m: {
      x: 10,
      y: 10,
    },
    /** 下中 */
    bm: {
      x: 10,
      y: 10,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: 10,
      y: 10,
    },
    /** 右 */
    r: {
      x: 10,
      y: 10,
    },
    /** 下右 */
    br: {
      x: 10,
      y: 10,
    },
  };
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 深度拷贝-路径点*/
  let pathPoints = JSON.parse(JSON.stringify(pelInfo.attrs.pathPoints.val));
  /** 数包对象点 */
  let ListObjPoint = Object.values(pathPoints);
  /** 数包点 */
  let ListPoint: any[] = [];
  /** 遍历 数包对象点  生成 数包点*/
  ListObjPoint.forEach((Item: any) => {
    let tempList = Object.values(Item);
    ListPoint.push(tempList);
  });
  /** 线生成器 */
  let lineGenerator = d3.line().curve(d3.curveNatural);
  /** 路径字符串 */
  let PathString = lineGenerator(ListPoint);
 // console.log(PathString)

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
   // console.log(pidVal)
    htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} id=${idVal} d='${PathString}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g></svg></div>`;
  }
  if (pidVal === "none") {
   // console.log(pidVal)
    htmlLabel = `<g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'><path id=${idVal} d='${PathString}' stroke='${strokeVal}' stroke-width='${strokeWidthVal}' stroke-linecap='${strokeLinecapVal}' stroke-dasharray='${strokeDasharrayVal}' stroke-dashoffset='${strokeDashoffsetVal}' opacity='${opacityVal}' fill='rgba(0,0,0,0)'>${anHtmlSet}</path></g>`;
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-Svg文本 */
const onUpdataHtmlSvgText = (pelInfo: any): any => {
 // console.log("✍ 更新标签-Svg文本")
 // console.log(pelInfo)
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 坐标 X*/
  let textLeftVal = Number(pelInfo.attrs.textLeft.val);
  /** 坐标 X*/
  let textTopVal = Number(pelInfo.attrs.textTop.val);

  //------------------------------------------------ 填充
  /** 填充颜色*/
  let fillVal = String(pelInfo.attrs.fill.val);
  /** 填充选项:1-颜色填充;2-图案填充;3-线性渐变填充;4-放射渐变填充;*/
  let fillOptVal = (pelInfo.attrs.fill.fillOpt);
  /** 填充图案*/
  let fillPatternVal = Number(pelInfo.attrs.fill.fillPattern);
  /** 填充尺寸*/
  let fillSizeVal = Number(pelInfo.attrs.fill.fillSize);
  /** 填充比例*/
  let fillRatioVal = Number(pelInfo.attrs.fill.fillRatio);
  /** 填充Id*/
  let fillIdVal = String(pelInfo.attrs.fill.fillId);
  /** 填充坐标x1*/
  let fillX1Val = Number(pelInfo.attrs.fill.fillX1);
  /** 填充坐标x2*/
  let fillX2Val = Number(pelInfo.attrs.fill.fillX2);
  /** 填充坐标y1*/
  let fillY1Val = Number(pelInfo.attrs.fill.fillY1);
  /** 填充坐标y2*/
  let fillY2Val = Number(pelInfo.attrs.fill.fillY2);
  /** 填充坐标cx*/
  let fillCXVal = Number(pelInfo.attrs.fill.fillCX);
  /** 填充坐标cy*/
  let fillCYVal = Number(pelInfo.attrs.fill.fillCY);
  /** 填充半径r*/
  let fillRVal = Number(pelInfo.attrs.fill.fillR);
  /** 填充偏移量*/
  let fillOffsetsVal = pelInfo.attrs.fill.offsets;

  /** 轮廓颜色值*/
  let strokeVal = String(pelInfo.attrs.stroke.val);
  /** 轮廓宽度*/
  let strokeWidthVal = Number(pelInfo.attrs.strokeWidth.val);
  /** 虚线值 */
  let strokeDasharrayVal = String(pelInfo.attrs.strokeDasharray.val);
  /** 虚线偏移值 */
  let strokeDashoffsetVal = Number(pelInfo.attrs.strokeDashoffset.val);
  /** 文本高度 */
  let FontSizeVal = Number(pelInfo.attrs.fontSize.val);
  /** 文本字体 */
  let FontFamilyVal = String(pelInfo.attrs.fontFamily.val);
  /** 对齐方式*/
  let TextAnchorVal = String(pelInfo.attrs.textAnchor.val);
  /** 划线设置*/
  let TextDecorationVal = String(pelInfo.attrs.textDecoration.val);
  /** 文本样式*/
  let FontStyleVal = String(pelInfo.attrs.fontStyle.val);
  /** 文本样式*/
  let FontWeightVal = String(pelInfo.attrs.fontWeight.val);
  /** 透明度 */
  let opacityVal = Number(pelInfo.attrs.opacity.val);
  /** 轮廓透明度 */
  let strokeOpacityVal = Number(pelInfo.attrs.strokeOpacity.val);
  /** 填充透明度 */
  let fillOpacityVal = Number(pelInfo.attrs.fillOpacity.val);
  /** 文本内容 */
  let textContentVal = String(pelInfo.attrs.textContent.val);
  /** 使用路径文本 */
  let usePathVal = Boolean(pelInfo.attrs.pathText.usePath);
  /** 切线方向的偏移 */
  let dxVal = Number(pelInfo.attrs.pathText.dx);
  /** 法线方向的偏移 */
  let dyVal = Number(pelInfo.attrs.pathText.dy);
  /** 路径超文本标签 */
  let pathHtmlVal = String(pelInfo.attrs.pathText.pathHtml);
  /** 路径id */
  let pathIdVal = String(pelInfo.attrs.pathText.pathId);


  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 声明动画标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签

  //------------------------------|公共-动画标签 textContent
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;
  /** 动画标签-文本内容*/
  let textContentAnHtml = ``;
  /** 动画标签-填充颜色*/
  let fillAnHtml = ``;
  /** 动画标签-轮廓颜色*/
  let strokeAnHtml = ``;
  /** 动画标签-轮廓宽度*/
  let strokeWidthAnHtml = ``;
  /** 动画标签-虚线 */
  let strokeDasharrayAnHtml = ``;
  /** 动画标签-虚线流动_动画 */
  let strokeDashoffsetAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;
  /** 动画标签-轮廓透明度 */
  let strokeOpacityAnHtml = ``;
  /** 动画标签-填充透明度 */
  let fillOpacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 文本内容 textContentVal;textContentAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.textContent.enable) {
   // console.log("文本内容 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.textContent, "", "XML");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      textContentVal = String(AnVal);
    }
    textContentAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充颜色 fillVal;fillAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fill.enable) {
   // console.log("填充颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.fill, "fill", "CSS");
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillVal = String(AnVal);
    }
    fillAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓颜色 strokeVal;strokeAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.stroke.enable) {
   // console.log("轮廓颜色 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.stroke, "stroke", "CSS");
    if (
      pelInfo.animations.stroke.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeVal = String(AnVal);
    }
    strokeAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 轮廓宽度 strokeWidthVal;strokeWidthAnHtml
 /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeWidth.enable) {
   // console.log("轮廓宽度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeWidth,
      "stroke-width",
      "XML"
    );
    if (
      pelInfo.animations.strokeWidth.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeWidthVal = Number(AnVal);
    }
    strokeWidthAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线 strokeDasharrayVal;strokeDasharrayAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDasharray.enable) {
   // console.log("虚线动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDasharray,
      "stroke-dasharray",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDasharrayVal = String(AnVal);
    }
    strokeDasharrayAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 虚线流动 strokeDashoffsetVal;strokeDashoffsetAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeDashoffset.enable) {
   // console.log("虚线流动 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeDashoffset,
      "stroke-dashoffset",
      "XML"
    );
    if (
      pelInfo.animations.strokeDasharray.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeDashoffsetVal = Number(AnVal);
    }
    strokeDashoffsetAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 透明度_元素 opacityVal;opacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.opacity.enable) {
   // console.log("透明度_元素 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.opacity,
      "opacity",
      "XML"
    );
    if (
      pelInfo.animations.opacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      opacityVal = Number(AnVal);
    }
    opacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 轮廓透明度 strokeOpacityVal;strokeOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.strokeOpacity.enable) {
   // console.log("轮廓透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.strokeOpacity,
      "stroke-opacity",
      "XML"
    );
    if (
      pelInfo.animations.strokeOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      strokeOpacityVal = Number(AnVal);
    }
    strokeOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 填充透明度 fillOpacityVal;fillOpacityAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.fillOpacity.enable) {
   // console.log("填充透明度 动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal,
      pelInfo.animations.fillOpacity,
      "fill-opacity",
      "XML"
    );
    if (
      pelInfo.animations.fillOpacity.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      fillOpacityVal = Number(AnVal);
    }
    fillOpacityAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml + //♈路径移动
    textContentAnHtml + //♈文本内容
    strokeAnHtml + //♈轮廓颜色
    strokeWidthAnHtml + //♈轮廓宽度
    strokeDasharrayAnHtml + //♈虚线
    strokeDashoffsetAnHtml + //♈虚线流动_动画
    fillAnHtml + //♈填充
    opacityAnHtml + //♈元素透明度
    strokeOpacityAnHtml + //♈轮廓透明度
    fillOpacityAnHtml; //♈填充透明度

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: textLeftVal - 5,
      y: textTopVal - 5,
    },
    /** 左 */
    l: {
      x: textLeftVal - 5,
      y: textTopVal,
    },
    /** 下左 */
    bl: {
      x: textLeftVal - 5,
      y: textTopVal + 5,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: textLeftVal,
      y: textTopVal - 5,
    },
    /** 中间 */
    m: {
      x: textLeftVal,
      y: textTopVal,
    },
    /** 下中 */
    bm: {
      x: textLeftVal,
      y: textTopVal + 5,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: textLeftVal + 5,
      y: textTopVal - 5,
    },
    /** 右 */
    r: {
      x: textLeftVal + 5,
      y: textTopVal,
    },
    /** 下右 */
    br: {
      x: textLeftVal + 5,
      y: textTopVal + 5,
    },
  };
 // console.log(PlacePoint)

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /* ★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  // 🐸 路径定义
  let pathDefs = `<defs><path id=${pathIdVal} d=${pathHtmlVal} stroke="rgba(0,0,0,0)" fill="none"/></defs>`
  // 🐸 文本路径定义
  let textPathDefs = `<textPath xlink:href="#${pathIdVal}">${textContentVal}</textPath></text>`;
  if (fillOptVal === 1/*颜色填充*/) {
    if (pidVal !== "none") {
      // 不使用路径文本
      if (!usePathVal) {
        htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><text id=${idVal} x='${textLeftVal}' y='${textTopVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textContentVal}${anHtmlSet}</text></svg></div>`;
      }
      // 使用路径文本
      if (usePathVal) {
        htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${pathDefs}<text id=${idVal} dx='${dxVal}' dy='${dyVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textPathDefs}${anHtmlSet}</text></g></svg></div>`;
      }
    }
    if (pidVal === "none") {
      // 不使用路径文本
      if (!usePathVal) {
        htmlLabel = `<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textContentVal}${anHtmlSet}</text>`;
      }
      // 使用路径文本
      if (usePathVal) {
        htmlLabel = `<g>${pathDefs}<text id=${idVal} dx='${dxVal}' dy='${dyVal}' style="stroke:${strokeVal}; stroke-width:${strokeWidthVal}; stroke-dasharray:${strokeDasharrayVal}; stroke-dashoffset:${strokeDashoffsetVal}; stroke:${strokeVal};fill:${fillVal};font-size:${FontSizeVal}px; font-family:${FontFamilyVal}; text-anchor:${TextAnchorVal}; text-decoration:${TextDecorationVal};font-style:${FontStyleVal};font-weight:${FontWeightVal};opacity:${opacityVal};stroke-opacity:${strokeOpacityVal};fill-opacity:${fillOpacityVal};">${textPathDefs}${anHtmlSet}</text></g>`;
      }
    }
  }
  if (fillOptVal === 2/*图案填充*/) {
    // 🐸 ★ 默认
    let defs = onPatternGenerator(fillPatternVal, fillVal, fillIdVal, fillSizeVal, fillRatioVal);
   // console.log(defs);
    if (pidVal !== "none") {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g></svg></div>`;
    }
    if (pidVal === "none") {
     // console.log(pidVal)
      htmlLabel = `<g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g>`;
    }
  }
  if (fillOptVal === 3/*线性渐变填充*/) {

    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }

    // 🐸 ★ 默认
    let defs = `<defs><linearGradient id=${fillIdVal} x1=${fillX1Val}% y1=${fillY1Val}% x2=${fillX2Val}% y2=${fillY2Val}% >${offset}</linearGradient></defs>`

    if (pidVal !== "none") {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g></svg></div>`;
    }
    if (pidVal === "none") {

     // console.log(pidVal)
      htmlLabel = `<g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g>`;
    }
  }
  if (fillOptVal === 4/*放射渐变填充*/) {
    // 🐸 ★ 偏移
    let offset = ``
    for (let index = 0; index < fillOffsetsVal.length; index++) {
      const element = fillOffsetsVal[index];
      offset = offset + `<stop offset=${element.offset}% style='stop-color:${element.color}'/> `
    }
    // 🐸 ★ 默认
    let defs = `<defs><radialGradient id=${fillIdVal} cx=${fillCXVal}% cy=${fillCYVal}% r=${fillRVal}% >${offset}</radialGradient></defs>`
    if (pidVal !== "none") {
     // console.log(pidVal)
      htmlLabel = `<div style='position:absolute;top:0px;left:0px;width:100%; height:100%;'><svg  version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='0 0 1024 1024'><g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g></svg></div>`;
    }
    if (pidVal === "none") {
     // console.log(pidVal)
      htmlLabel = `<g>${defs}<text id=${idVal} x='${textLeftVal}' y='${textTopVal}' stroke=${strokeVal} stroke-width=${strokeWidthVal} stroke-dasharray=${strokeDasharrayVal} stroke-dashoffset=${strokeDashoffsetVal} stroke=${strokeVal} fill=url(#${fillIdVal}) font-size=${FontSizeVal}px font-family=${FontFamilyVal} text-anchor=${TextAnchorVal} text-decoration=${TextDecorationVal} font-style=${FontStyleVal} font-weight=${FontWeightVal} opacity:${opacityVal} stroke-opacity=${strokeOpacityVal} fill-opacity=${fillOpacityVal}>${textContentVal}${anHtmlSet}</text></g>`;
    }
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-svg图片*/
const onUpdataHtmlDIVImage = (pelInfo: any): any => {
 // console.log("✍ 更新标签-svg图片")
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  /** 坐标 X */
  let left = Number(pelInfo.attrs.left.val);
  /** 坐标 X */
  let top = Number(pelInfo.attrs.top.val);
  /** 宽度值 */
  let width = Number(pelInfo.attrs.width.val);
  /** 高度值 */
  let height = Number(pelInfo.attrs.height.val);
  /** 图片数据  */
  let imageData = String(pelInfo.attrs.imageData.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 建立 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: left,
      y: top,
    },
    /** 左 */
    l: {
      x: left,
      y: top + height / 2,
    },
    /** 下左 */
    bl: {
      x: left,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: left + width / 2,
      y: top,
    },
    /** 中间 */
    m: {
      x: left + width / 2,
      y: top + height / 2,
    },
    /** 下中 */
    bm: {
      x: left + width / 2,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: left + width,
      y: top,
    },
    /** 右 */
    r: {
      x: left + width,
      y: top + height / 2,
    },
    /** 下右 */
    br: {
      x: left + width,
      y: top + height,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;
  if (pidVal !== "none") {
    htmlLabel = `<g vector-effect="non-scaling-stroke"><image preserveAspectRatio="none" vector-effect="non-scaling-stroke"  xlink:href='${imageData}' x='${left}px' y='${top}px' width='${width}px' height='${height}px'></image></g>`;
  }
  if (pidVal === "none") {
    htmlLabel = `<g vector-effect="non-scaling-stroke"><image preserveAspectRatio="none" vector-effect="non-scaling-stroke" xlink:href=${imageData} x='${left}px' y='${top}px' width='${width}px' height='${height}px'></image></g>`;
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};


/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ DIV图元
/**————————————————————————————————————————————————————————————————————————————————————————————————*/
/** 更新标签-DIV文本 */
const onUpdataHtmlDIVText = (pelInfo: any): any => {
 // console.log("✍ 更新标签-DIV文本")
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);
  /** 坐标x */
  let leftVal = Number(pelInfo.attrs.left.val);
  /** 坐标y */
  let topVal = Number(pelInfo.attrs.top.val);
  /** 宽 */
  let widthVal = Number(pelInfo.attrs.width.val);
  /** 高  */
  let heightVal = Number(pelInfo.attrs.height.val);
  /** 旋转角度 */
  let rotateVal = Number(pelInfo.attrs.rotate.val);
  /** 边框宽度 */
  let borderWidthVal = Number(pelInfo.attrs.borderWidth.val);
  /** 边框样式 */
  let borderStyleVal = String(pelInfo.attrs.borderStyle.val);
  /** 边框颜色 */
  let borderColorVal = String(pelInfo.attrs.borderColor.val);
  /** 边框圆角 */
  let borderRadiusVal = String(pelInfo.attrs.borderRadius.val);
  /** 文本高度 */
  let fontSizeVal = String(pelInfo.attrs.fontSize.val);
  /** 字符之间的间距 */
  let letterSpacVal = String(pelInfo.attrs.letterSpac.val);
  /** 字间距*/
  let wordSpacVal = String(pelInfo.attrs.wordSpac.val);
  /** 文本样式 */
  let fontStyleVal = String(pelInfo.attrs.fontStyle.val);
  /** 文本字体 */
  let fontFamilyVal = String(pelInfo.attrs.fontFamily.val);
  /** 粗细 */
  let fontWeightVal = String(pelInfo.attrs.fontWeight.val);
  /** 文本水平对齐方式 */
  let textAlignVal = String(pelInfo.attrs.textAlign.val);
  /** 第一行的缩进 */
  let textIndentVal = Number(pelInfo.attrs.textIndent.val);
  /** 行高 */
  let rowHeightVal = Number(pelInfo.attrs.rowHeight.val);
  /** 字体内容 */
  let fontContentVal = String(pelInfo.attrs.fontContent.val);
  /** 字体颜色 */
  let fontColorVal = String(pelInfo.attrs.fontColor.val);
  /** 背景颜色 */
  let backgroundColorVal = String(pelInfo.attrs.backgroundColor.val);
  /** 水平阴影 */
  let shadowHorizontalVal = String(pelInfo.attrs.shadowHorizontal.val);
  /** 垂直阴影 */
  let shadowVerticalVal = String(pelInfo.attrs.shadowVertical.val);
  /** 模糊阴影 */
  let shadowvagueVal = String(pelInfo.attrs.shadowvague.val);
  /** 阴影颜色 */
  let shadowColorVal = String(pelInfo.attrs.shadowColor.val);
  /** 叠放层级  */
  let zIndex = Number(pelInfo.attrs.zIndex.val);

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: leftVal,
      y: topVal,
    },
    /** 左 */
    l: {
      x: leftVal,
      y: topVal + heightVal / 2,
    },
    /** 下左 */
    bl: {
      x: leftVal,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: leftVal + widthVal / 2,
      y: topVal,
    },
    /** 中间 */
    m: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal / 2,
    },
    /** 下中 */
    bm: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: leftVal + widthVal,
      y: topVal,
    },
    /** 右 */
    r: {
      x: leftVal + widthVal,
      y: topVal + heightVal / 2,
    },
    /** 下右 */
    br: {
      x: leftVal + widthVal,
      y: topVal + heightVal,
    },
  };
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = `<div style='position: absolute;width: ${widthVal}px; height: ${heightVal}px;top: ${topVal}px; left: ${leftVal}px; border: ${borderWidthVal}px ${borderStyleVal} ${borderColorVal};border-radius: ${borderRadiusVal}px; transform: rotate(${rotateVal}deg);font-size: ${fontSizeVal}px;text-indent: ${textIndentVal}px;line-height: ${rowHeightVal};letter-spacing: ${letterSpacVal}px;word-spacing: ${wordSpacVal}px; font-style: ${fontStyleVal};font-weight: ${fontWeightVal};font-family: ${fontFamilyVal};text-align: ${textAlignVal};text-shadow: ${shadowHorizontalVal}px ${shadowVerticalVal}px ${shadowvagueVal}px ${shadowColorVal};background-color: ${backgroundColorVal};color: ${fontColorVal};z-index:${zIndex};'>${fontContentVal}</div>`;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);

      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};


/** 更新标签-DIV块 */
const onUpdataHtmlDIVBlock = (pelInfo: any): any => {
 // console.log("✍ 更新标签-DIV块")
 // console.log(pelInfo)
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  //------------------------------|变换
  /** 旋转值 */
  let rotateVal = 0;
  /** 缩放值 */
  let scaleVal = 1;
  /** 水平移动值 */
  let translateXVal = 0;
  /** 垂直移动值 */
  let translateYVal = 0;
  /** 水平拉伸值 */
  let skewXVal = 0;
  /** 垂直拉伸值 */
  let skewYVal = 0;

  /** 视图盒子x坐标 */
  let boxLeftVal = Number(pelInfo.attrs.boxLeft.val);
  /** 视图盒子y坐标 */
  let boxTopVal = Number(pelInfo.attrs.boxTop.val);
  /** 视图盒子宽 */
  let boxWidthVal = Number(pelInfo.attrs.boxWidth.val);
  /** 视图盒子高 */
  let boxHeightVal = Number(pelInfo.attrs.boxHeight.val);


  let left = Number(pelInfo.attrs.left.val);
  let top = Number(pelInfo.attrs.top.val);
  let width = Number(pelInfo.attrs.width.val);
  let height = Number(pelInfo.attrs.height.val);

  /** 叠放层级  */
  let zIndex = Number(pelInfo.attrs.zIndex.val);
  /** 旋转  */
  let rotate = Number(pelInfo.attrs.rotate.val);
  /** 块标签  */
  let blockHtml = pelInfo.attrs.blockHtml.val;

  //-----------------------------------|公共动画
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 动画标签声明
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|公共-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平移动 */
  let translateXAnHtml = ``;
  /** 动画标签-垂直移动 */
  let translateYAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-水平动画 */
  let leftAnHtml = ``;
  /** 动画标签-垂直动画 */
  let topAnHtml = ``;
  /** 动画标签-透明度_元素 */
  let opacityAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█ 变换动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 旋转 rotateVal rotateAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.rotate.enable) {
   // console.log("旋转_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.rotate, "roate", "XML");
    if (
      pelInfo.animations.rotate.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      rotateVal = Number(AnVal);
    }
    rotateAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 缩放 scaleVal scaleAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.scale.enable) {
   // console.log("缩放_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.scale, "", "XML");
    if (
      pelInfo.animations.scale.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      scaleVal = Number(AnVal);
    }
    scaleAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平移动 translateXVal translateXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateX.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateX, "", "XML");
    if (
      pelInfo.animations.translateX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateXVal = Number(AnVal);
    }
    translateXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直移动 translateYVal translateYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.translateY.enable) {
   // console.log("平移_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.translateY, "", "XML");
    if (
      pelInfo.animations.translateY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      translateYVal = Number(AnVal);
    }
    translateYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 水平拉伸 skewXVal skewXAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewX.enable) {
   // console.log("水平拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewX, "", "XML");
    if (
      pelInfo.animations.skewX.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewXVal = Number(AnVal);
    }
    skewXAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 垂直拉伸 skewYVal skewYAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.skewY.enable) {
   // console.log("垂直拉伸_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.skewY, "", "XML");
    if (
      pelInfo.animations.skewY.opt_an_model !==
      3 /*动画模式 1-值动画;2-值转换动画;3-自动画*/
    ) {
      skewYVal = Number(AnVal);
    }
    skewYAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 线性移动 lineMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.lineMove.enable) {
   // console.log("线性移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.lineMove, "", "XML");
    lineMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 路径移动 pathMoveAnHtml
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  if (pelInfo.animations.pathMove.enable) {
   // console.log("路径移动_动画")
    let [AnVal, AnHtml] = onAnimationHandle(pidVal, pelInfo.animations.pathMove, "", "XML");
    pathMoveAnHtml = String(AnHtml);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    //-----------------------------------|公共动画
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    translateXAnHtml + //♈水平移动
    translateYAnHtml + //♈垂直移动
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml //♈路径移动
    ;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 位置点 */
  let PlacePoint: PlaceType = {
    // 🦢 ----------| ★★ 位置点-左
    /** 上左 */
    tl: {
      x: left,
      y: top,
    },
    /** 左 */
    l: {
      x: left,
      y: top + height / 2,
    },
    /** 下左 */
    bl: {
      x: left,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-中
    /** 上中 */
    tm: {
      x: left + width / 2,
      y: top,
    },
    /** 中间 */
    m: {
      x: left + width / 2,
      y: top + height / 2,
    },
    /** 下中 */
    bm: {
      x: left + width / 2,
      y: top + height,
    },

    // 🦢 ----------| ★★ 位置点-右
    /** 上右 */
    tr: {
      x: left + width,
      y: top,
    },
    /** 右 */
    r: {
      x: left + width,
      y: top + height / 2,
    },
    /** 下右 */
    br: {
      x: left + width,
      y: top + height,
    },
  };

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``
  if (pidVal !== "none") {
    htmlLabel = `<div style='position: absolute;width:${width}px; height:${height}px;top: ${top}px; left: ${left}px;transform: rotate(${rotate}deg); z-index:${zIndex};'><svg width=${width} height=${height} version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox='${boxLeftVal} ${boxTopVal} ${boxWidthVal} ${boxHeightVal}'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${blockHtml} ${anHtmlSet}</g></svg></div>`;
  }
  if (pidVal === "none") {
    htmlLabel = `<div style='position: absolute;width:${width}px; height:${height}px;top: ${top}px; left: ${left}px;transform: rotate(${rotate}deg); z-index:${zIndex};'><svg width=${width} height=${height} version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"  viewBox='${boxLeftVal} ${boxTopVal} ${boxWidthVal} ${boxHeightVal}'><g style='transform: translate(${translateXVal}px ${translateYVal}px) rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg)'>${blockHtml} ${anHtmlSet}</g></svg></div>`;
  }
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));
  copyPels.forEach((element: any) => {
   // console.log(element.key);
    if (element.key === pelInfo.key) {
     // console.log(element);
      element.htmls = htmlLabel; // 文本标记标签
      element.place = PlacePoint; // 位置点
    }
  });
  workStore.pels = copyPels;
  return htmlLabel;
};

/** 更新标签-包*/
const onUpdataHtmWrap = (pelInfo: any) => {
  // console.log("✍ 更新标签-包")
 // console.log(pelInfo)
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 变量转储
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** id值*/
  let idVal = String(pelInfo.key);
  /** 父id值 */
  let pidVal = String(pelInfo.parent);

  /** 旋转值*/
  let rotateVal = Number(pelInfo.attrs.rotate.val);
  /** 缩放值*/
  let scaleVal = Number(pelInfo.attrs.scale.val);
  /** 水平拉伸*/
  let skewXVal = Number(pelInfo.attrs.skewX.val);
  /** 垂直拉伸*/
  let skewYVal = Number(pelInfo.attrs.skewY.val);
  /** 坐标X值*/
  let leftVal = Number(pelInfo.attrs.left.val);
  /** 坐标Y值*/
  let topVal = Number(pelInfo.attrs.top.val);
  /** 叠放层级  */
  let zIndexVal = Number(pelInfo.attrs.zIndex.val);
  /** 画布宽度 */
  let canvasWidth = Number(canvasStore.canvasAttr.canvasWidth);
  /** 画布高度 */
  let canvasHeight = Number(canvasStore.canvasAttr.canvasHeight);
  /** 宽度值 */
  let widthVal = canvasWidth / scaleVal;
  /** 高度值 */
  let heightVal = canvasHeight / scaleVal;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 声明动画标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 动画标签集 */
  let anHtmlSet = ``;

  //------------------------------|属性-动画标签
  /** 动画标签-水平动画 */
  let leftAnHtml = ``;
  /** 动画标签-垂直动画 */
  let topAnHtml = ``;
  /** 动画标签-圆半径 */
  let radiusAnHtml = ``;

  //------------------------------|公共-动画标签
  /** 动画标签-旋转 */
  let rotateAnHtml = ``;
  /** 动画标签-缩放 */
  let scaleAnHtml = ``;
  /** 动画标签-水平拉伸 */
  let skewXAnHtml = ``;
  /** 动画标签-垂直拉伸 */
  let skewYAnHtml = ``;
  /** 动画标签-线性移动 */
  let lineMoveAnHtml = ``;
  /** 动画标签-路径移动 */
  let pathMoveAnHtml = ``;

  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/
  //█属性-动画                                                                      █
  /** ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■*/

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 动画合并
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  anHtmlSet =
    rotateAnHtml + //♈旋转
    scaleAnHtml + //♈缩放
    skewXAnHtml + //♈水平拉伸
    skewYAnHtml + //♈垂直拉伸
    lineMoveAnHtml + //♈线性移动
    pathMoveAnHtml; //♈路径移动

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  //★ 建立 文本标记标签
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let htmlLabel = ``;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历子数据
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  try {
    if (pelInfo.children.length > 0) {
     // console.log("★ pelInfo.children.length > 0 遍历")
      let ErgodicData = pelInfo.children;
      // 🐸  ★ 迭代-遍历子数据
      function wrapUpdata(ErgodicData: any) {
       // console.log("包裹迭代-遍历子数据")
        ErgodicData.forEach((pelDate: any) => {
          let PelType = pelDate.type;
         // console.log(SvgDate)
          if (
            PelType === "horizontaLine" /*水平线*/ ||
            PelType === "verticalLine" /*垂直线*/ ||
            PelType === "slantLine" /*斜线*/
          ) {
            htmlLabel = htmlLabel + onUpdataHtmlLine(pelDate);
          }
          if (PelType === "circle" /*圆*/) {
            htmlLabel = htmlLabel + onUpdataHtmlCircle(pelDate);
          }
          if (PelType === "ellipse" /*椭圆*/) {
            htmlLabel = htmlLabel + onUpdataHtmlEllipse(pelDate);
          }
          if (PelType === "arc" /*三点弧线*/) {
            htmlLabel = htmlLabel + onUpdataHtmlArc(pelDate);
          }
          if (PelType === "circlePolygon" /*圆分多边形*/) {
            htmlLabel = htmlLabel + onUpdataHtmlCirclePolygon(pelDate);
          }
          if (PelType === "rectangle" /*矩形*/) {
            htmlLabel = htmlLabel + onUpdataHtmlRectangle(pelDate);
          }
          if (PelType === "sector" /*扇形*/) {
          }
          if (PelType === "polygon" /*多边形*/) {
            htmlLabel = htmlLabel + onUpdataHtmlPolygon(pelDate);
          }
          if (PelType === "polyline" /*折线*/) {
            htmlLabel = htmlLabel + onUpdataHtmlPolyline(pelDate);
          }
          if (PelType === "path" /*路径*/) {
            htmlLabel = htmlLabel + onUpdataHtmlPath(pelDate);
          }
          if (PelType === "svgText" /*Svg文本*/) {
            htmlLabel = htmlLabel + onUpdataHtmlSvgText(pelDate);
          }
          // ————————————————————————————————————————————————————————————————————————————————| DIV图元
          if (PelType === "divText" /*DIV文本*/) {
            htmlLabel = htmlLabel + onUpdataHtmlDIVText(pelDate);
          }
          if (PelType === "svgImage" /*图片*/) {
            htmlLabel = htmlLabel + onUpdataHtmlDIVImage(pelDate);
          }
          if (PelType === "divBlock" /*DIV块*/) {
            htmlLabel = htmlLabel + onUpdataHtmlDIVBlock(pelDate);
          }

          /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
          // 🐸 迭代
          /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
          try {
            if (pelDate.children.length > 0) {
             // console.log("有子数据-分边遍历")
              let childrenData = pelDate.children;
              childrenData.forEach((element: any) => {
                wrapUpdata(element);
              });
            }
          } catch (error) { }
        });
      }
      wrapUpdata(ErgodicData);
     // console.log(htmlLabel)
    }
  } catch (error) { }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 合并标签及动画
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  let mergeHtml = `<div id=${idVal} style='position:absolute;width:1024px; height:1024px;top:${topVal}px; left:${leftVal}px;transform: rotate(${rotateVal}deg) scale(${scaleVal}) skewX(${skewXVal}deg) skewY(${skewYVal}deg); z-index:${zIndexVal};'>${htmlLabel} ${anHtmlSet}</div>`;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 位置点
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // ——————————————————————————————————————————————————————————————| ★ 位置点
  /** 位置点 */
  let PlacePoint: PlaceType = {
    /** 上左 */
    tl: {
      x: leftVal,
      y: topVal,
    },
    /** 上中 */
    tm: {
      x: leftVal + widthVal / 2,
      y: topVal,
    },
    /** 上右 */
    tr: {
      x: leftVal + widthVal,
      y: topVal,
    },
    /** 左 */
    l: {
      x: leftVal,
      y: topVal + heightVal / 2,
    },
    /** 中间 */
    m: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal / 2,
    },
    /** 右 */
    r: {
      x: leftVal + widthVal,
      y: topVal + heightVal / 2,
    },
    /** 下左 */
    bl: {
      x: leftVal,
      y: topVal + heightVal,
    },
    /** 下中 */
    bm: {
      x: leftVal + widthVal / 2,
      y: topVal + heightVal,
    },
    /** 下右 */
    br: {
      x: leftVal + widthVal,
      y: topVal + heightVal,
    },
  };


  /** 深度拷贝-图元数据 */
  let copyPels = JSON.parse(JSON.stringify(workStore.pels));

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历图元数据，更新-属性;文本标记标签;位置点;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  for (let indexA = 0; indexA < copyPels.length; indexA++) {
    let pelItem = copyPels[indexA];
   // console.log(element.key);
    if (pelItem.key === pelInfo.key) {
     // console.log(element);
      pelItem.attrs.wrapHtml.val = mergeHtml; // 文本标记标签
      pelItem.htmls = mergeHtml; // 文本标记标签
      pelItem.place = PlacePoint; // 位置点
    }
  };
  workStore.pels = copyPels;
  return htmlLabel;
};

/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ 更新-标签
/**————————————————————————————————————————————————————————————————————————————————————————————————*/
/** 迭代更新-标签 */
const onUpdataHtmlIteration = (pelInfo: any) => {
 // console.log("更新标签")

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历 图元数据
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  /** 图元类型 */
  let PelType = pelInfo.type;
 // console.log(PelType)
  if (PelType === "wrap" /*包*/) {
    onUpdataHtmWrap(pelInfo);
  }
  if (
    PelType === "horizontaLine" /*水平线*/ ||
    PelType === "verticalLine" /*垂直线*/ ||
    PelType === "slantLine" /*斜线*/
  ) {
    onUpdataHtmlLine(pelInfo);
  }
  if (PelType === "circle" /*圆*/) {
    onUpdataHtmlCircle(pelInfo);
  }
  if (PelType === "ellipse" /*椭圆*/) {
    onUpdataHtmlEllipse(pelInfo);
  }
  if (PelType === "arc" /*三点弧线*/) {
    onUpdataHtmlArc(pelInfo);
  }
  if (PelType === "circlePolygon" /*圆分多边形*/) {
    onUpdataHtmlCirclePolygon(pelInfo);
  }
  if (PelType === "rectangle" /*矩形*/) {
    onUpdataHtmlRectangle(pelInfo);
  }
  if (PelType === "sector" /*扇形*/) {
  }
  if (PelType === "polygon" /*多边形*/) {
    onUpdataHtmlPolygon(pelInfo);
  }
  if (PelType === "polyline" /*折线*/) {
    onUpdataHtmlPolyline(pelInfo);
  }
  if (PelType === "path" /*路径*/) {
    onUpdataHtmlPath(pelInfo);
  }
  if (PelType === "svgText" /*Svg文本*/) {
    onUpdataHtmlSvgText(pelInfo);
  }
  if (PelType === "svgImage" /*图片*/) {
    onUpdataHtmlDIVImage(pelInfo);
  }
  // ————————————————————————————————————————————————————————————————————————————————| DIV图元
  if (PelType === "divText" /*DIV文本*/) {
    onUpdataHtmlDIVText(pelInfo);
  }

  if (PelType === "divBlock" /*DIV块*/) {
    onUpdataHtmlDIVBlock(pelInfo);
  }

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 迭代
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  try {
    if (pelInfo.children.length > 0) {
      /** 迭代-根据键添加图元 */
     // console.log("       ...... 迭代-设置图元属性")
      /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
      // 🐸 遍历 子数据
      /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
      let childrens = pelInfo.children;
      for (let index = 0; index < childrens.length; index++) {
        const subDataSet = childrens[index];
        onUpdataHtmlIteration(subDataSet); //迭代更新-标签
      }
    }
  } catch (error) {
   // console.log(error)
  }
};

/** 更新标签 */
export const onUpdataHtml = () => {
 // console.log("更新标签")

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历 图元数据
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  workStore.pels.forEach((pelInfo: any /*图元参数*/) => {
    /** 图元类 */
    let PelType = pelInfo.type;
   // console.log(PelType)
    if (PelType === "wrap" /*包*/) {
      onUpdataHtmWrap(pelInfo);
    }
    if (
      PelType === "horizontaLine" /*水平线*/ ||
      PelType === "verticalLine" /*垂直线*/ ||
      PelType === "slantLine" /*斜线*/
    ) {
      onUpdataHtmlLine(pelInfo);
    }
    if (PelType === "circle" /*圆*/) {
      onUpdataHtmlCircle(pelInfo);
    }
    if (PelType === "ellipse" /*椭圆*/) {
      onUpdataHtmlEllipse(pelInfo);
    }
    if (PelType === "arc" /*三点弧线*/) {
      onUpdataHtmlArc(pelInfo);
    }
    if (PelType === "circlePolygon" /*圆分多边形*/) {
      onUpdataHtmlCirclePolygon(pelInfo);
    }
    if (PelType === "rectangle" /*矩形*/) {
      onUpdataHtmlRectangle(pelInfo);
    }
    if (PelType === "sector" /*扇形*/) {
    }
    if (PelType === "polygon" /*多边形*/) {
      onUpdataHtmlPolygon(pelInfo);
    }
    if (PelType === "polyline" /*折线*/) {
      onUpdataHtmlPolyline(pelInfo);
    }
    if (PelType === "path" /*路径*/) {
      onUpdataHtmlPath(pelInfo);
    }
    if (PelType === "svgText" /*Svg文本*/) {
      onUpdataHtmlSvgText(pelInfo);
    }
    if (PelType === "svgImage" /*图片*/) {
      onUpdataHtmlDIVImage(pelInfo);
    }
    // ————————————————————————————————————————————————————————————————————————————————| DIV图元
    if (PelType === "divText" /*DIV文本*/) {
      onUpdataHtmlDIVText(pelInfo);
    }
    if (PelType === "divBlock" /*DIV块*/) {
      onUpdataHtmlDIVBlock(pelInfo);
    }
  });
};

/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ 更新-图元属性
/**————————————————————————————————————————————————————————————————————————————————————————————————*/

/** 迭代更新-图元属性
 * @参数_DataSet    数据
 * @参数_Id         图元Id
 * @参数_NewVal     新变量
 */
const onUpdataPelAttrsIteration = (
  dataSet: any,
  id: string,
  pelInfo: any,
  parent: string
) => {
 // console.log("♈ 设置-图元属性")
  /** ◆ 遍历属性 */
  if (dataSet !== undefined) {
    if (dataSet.key === id) {
      dataSet.label = pelInfo.label;
      dataSet.attrs = pelInfo.attrs;
      dataSet.parent = parent;
      if (pelInfo.type === 'wrap') {
        dataSet.an_vals = pelInfo.an_vals;
      }
    }
    /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    // 🐸 迭代
    /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    try {
      if (dataSet.children.length > 0) {
        /** 迭代-根据键添加图元 */
       // console.log("       ...... 迭代-设置图元属性")
        /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        // 🐸 遍历 子数据
        /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        let childrens = dataSet.children;
        for (let index = 0; index < childrens.length; index++) {
          const subDataSet = childrens[index];
          let parent = String(dataSet.key);
          onUpdataPelAttrsIteration(subDataSet, id, pelInfo, parent); //迭代设置-图元属性
        }
      }
    } catch (error) {
     // console.log(error)
    }
  }
};

/** 更新-图元属性 */
export const onUpdataPelAttrs = () => {
 // console.log("♈ 动画-图元属性")

  /** 图元属性 */
  let pelInfo = JSON.parse(JSON.stringify(canvasStore.selectedPel));
  /** 图元Id */
  let id = canvasStore.selectedPel.key;
  /** 父Id */
  let parent = canvasStore.selectedPel.parent;

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  for (let index = 0; index < workStore.pels.length; index++) {
    const dataSet = workStore.pels[index];
    onUpdataPelAttrsIteration(dataSet, id, pelInfo, parent);
  }
};

/**————————————————————————————————————————————————————————————————————————————————————————————————*/
//                                ★ 更新-图元位置
/**————————————————————————————————————————————————————————————————————————————————————————————————*/

/** 迭代更新-图元位置
 * @参数_DataSet    数据
 * @参数_Id         图元Id
 * @参数_NewVal     新变量
 */
const onUpdataPelPlaceIteration = (
  dataSet: any,
  id: string,
  pelInfo: any,
) => {
 // console.log("♈ 设置-图元位置")
  /** ◆ 遍历属性 */
  if (dataSet !== undefined) {
    if (dataSet.key === id) {
      dataSet.place = pelInfo.place;
    }
    /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    // 🐸 迭代
    /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    try {
      if (dataSet.children.length > 0) {
        /** 迭代-根据键添加图元 */
       // console.log("       ...... 迭代-设置图元位置")
        /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        // 🐸 遍历 子数据
        /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
        let childrens = dataSet.children;
        for (let index = 0; index < childrens.length; index++) {
          const subDataSet = childrens[index];
          onUpdataPelPlaceIteration(subDataSet, id, pelInfo); //迭代设置-图元属性
        }
      }
    } catch (error) {
     // console.log(error)
    }
  }
};

/** 更新-图元位置 */
export const onUpdataPelPlace = () => {
 // console.log("♈ 动画-图元位置")
  /** 图元Id */
  let id = canvasStore.selectedPel.key;
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 更新位置参数
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  try {

    let boxSize = document.getElementById(id).getBoundingClientRect()
   // console.log(boxSize)
    let leftVal = boxSize.left;
    let topVal = boxSize.top;
    let widthVal = boxSize.width;
    let heightVal = boxSize.height;
    canvasStore.selectedPel.place.tl.x = leftVal;
    canvasStore.selectedPel.place.tl.y = topVal;
    canvasStore.selectedPel.place.tm.x = leftVal + (widthVal / 2);
    canvasStore.selectedPel.place.tm.y = topVal;
    canvasStore.selectedPel.place.tr.x = leftVal + widthVal;
    canvasStore.selectedPel.place.tr.y = topVal;
    canvasStore.selectedPel.place.l.x = leftVal;
    canvasStore.selectedPel.place.l.y = topVal + (heightVal / 2);
    canvasStore.selectedPel.place.m.x = leftVal + (widthVal / 2);
    canvasStore.selectedPel.place.m.y = topVal + (heightVal / 2);
    canvasStore.selectedPel.place.r.x = leftVal + widthVal;
    canvasStore.selectedPel.place.r.y = topVal + (heightVal / 2);
    canvasStore.selectedPel.place.bl.x = leftVal;
    canvasStore.selectedPel.place.bl.y = topVal + heightVal;
    canvasStore.selectedPel.place.bm.x = leftVal + (widthVal / 2);
    canvasStore.selectedPel.place.bm.y = topVal + heightVal;
    canvasStore.selectedPel.place.br.x = leftVal + widthVal;
    canvasStore.selectedPel.place.br.y = topVal + heightVal;
  } catch (error) {

  }


  /** 图元参数 */
  let pelInfo = JSON.parse(JSON.stringify(canvasStore.selectedPel));

  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  // 🐸 遍历
  /**~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
  workStore.pels.forEach((dataSet: any) => {
    onUpdataPelPlaceIteration(dataSet, id, pelInfo);
  });
};

